\documentclass[a4paper,10pt]{article}
\usepackage[spanish]{babel} % Para división en sílabas español.
\usepackage[utf8]{inputenc} % Para poner acentos.
\usepackage{graphicx} % Paquete para ingresar gráficos
\usepackage{hyperref}
\usepackage{fancybox}

%Encabezado y Pié de página
\input{EncabezadoYPie/EncabezadoyPie.tex}
%Carátula del Trabajo
\title{ \input{Portada/Portada.tex} }

\begin{document}
	\maketitle %Hace que el título anterior sea el principal del documento
	\newpage

	\tableofcontents %Esta línea genera un indice a partir de las secciones y subsecciones creadas en el documento
	\newpage

	\section{Objetivos}
		El objetivo del presente trabajo consiste en familiarizarnos con el conjunto de instrucciones MIPS y el concepto de ABI, 
		realizando una versión simplificada del comando \emph{wc}.
		\vspace{1cm}
 	\section{Introducción Teórica}
		\label{sec:InfoTeo}
		Para cumplir con los objetivos de esta entrega se deberá implementar las funciones \emph{wc} y \emph{count} en assembly de MIPS32. El resto del programa se realizará en lenguaje C.
		A continuación se explicarán brevemente los conceptos más importantes del ABI utilizado y el conjunto de instrucciones necesarios para desarrollar el trabajo:
		\vspace{0.5cm}
		\subsection{MIPS}
			La arquitectura MIPS presenta 32 registros de propósito general (de 32 bits). Además presenta dos registros especiales para mantener los resultados provenientes de una multiplicación o división y un coprocesador que agrega otros 32 registros de punto flotante (también de 32 bits).
		\vspace{0.5cm}

		\subsection{ABI}
			 Se presentan aquellas consideraciones utilizadas en la presente entrega, sin hacer detalle de otros aspectos que fueron irrelevantes a la hora de realizar la misma.
			\begin{itemize}
			
			\item Los registros \emph{ra, sp, fp, gp, s0, s1..s7}, y \emph{f20..f30} deben ser guardados por la función llamada en caso de que ésta los modifique. 
			
			\item Cada función crea siempre su \emph{stack frame} (pila de llamadas), la cual se compone de áreas de tamaño multiplo de 8 bytes y alineadas a 8 bytes, agregando el \emph{padding} necesario cuando así se requiera.

			\item El \emph{stack frame} posee una cantidad variable de áreas, pero siempre debe incluir una de registros salvados (\emph{saved Regs. Area}). Otras posibles áreas son: la de registros de punto flotante (\emph{Floats Regs. Area}), la de variables locales (\emph{Local and Temporary Variables Area}) y la de argumentos (\emph{Arg Building Area}).
			
			\item En \emph{saved Regs. Area} deben guardarse siempre \emph{fp} (puntero del frame) y \emph{gp} (puntero global y de contexto). Para el caso de una función que no es hoja, debe guardarse \emph{ra} (dirección de retorno). Además, si cualquiera de los registros \$16..\$23 o \$29..\$31 son modificados dentro de la función llamada, deben ser salvados antes de su uso y restaurado antes del retorno a la función que llama.
			
			\item En \emph{Floating-Point Registers Save Area} deben salvarse los registros \emph{f20} a \emph{f30} en el caso de que sean utilizados, teniendo en cuenta las mismas consideraciones que en el punto anterior.
			
			\item El \emph{Arg Building Area} se crea cuando la función no es hoja, posee al menos 16 bytes aún cuando los argumentos de la función llamada sean menos. Cuando los primeros cuatro argumentos son punteros o enteros se pasan en a0 a a3 y son almacenados en ésta área por la función llamada.
			
			\item Los registros son salvados en orden numérico, es decir que los registros numerados más alto se guardan en posiciones más altas de la memoria.

			\end{itemize}
	
		\subsection{Instrucciones}
			\begin{itemize}			
			\item\textbf{Aritméticas}
			\newline
			\newline
			\textbf{Suma:} add \$1, \$2, \$3 (suma \$2 con \$3  y almacena en \$1)
			\newline			
			\newline
			\textbf{Suma sin signo:} addu \$1, \$2, \$3 (suma dos registros sin signo)
			\newline
			\newline
			\textbf{Resta:} sub \$1, \$2, \$3 (resta \$2 con \$3  y almacena en \$1)
			\newline
			\newline
			\textbf{Resta sin signo:} subu \$1, \$2, \$3 (resta dos registros sin signo (\$2 con \$3)  y almacena en \$1)
			\newline
			\newline
			\textbf{Suma inmediata:} addi \$1, \$2, CONST (suma \$2 con CONST  y almacena en \$1)
			\newline	
			\newline
			\textbf{Multiplicación:} mul \$1, \$2 (multiplica dos registros y guarda el resultado de 64 bits en dos registros especiales de la memoria (LO para la parte menos significativa y HI para la más significativa)
			\newline
			\newline
			\textbf{División:} div \$1, \$2 (divide \$1 en \$2, guardando el cociente en LO y el resto en HI)

			\item\textbf{Load/Store}
			\newline
			\newline
			\textbf{Carga de dirección:} la \$1, etiqueta (carga la direccion de memoria de una etiqueta en el registro \$1)
			\newline
			\newline
			\textbf{Carga de palabra:} lw \$1,CONST(\$1) (carga la palabra almacenada desde \$2 + CONST (4 bytes) en el registro \$1)
			\newline
			\newline
			\textbf{Carga de media palabra:} lh \$1,CONST(\$2) (carga la media palabra almacenada desde \$2 + CONST (2 bytes) en el registro \$1)
			\newline
			\newline
			\textbf{Carga de byte:} lb \$1,CONST(\$2) (carga el byte almacenado en \$2 + CONST en el registro \$1)
			\newline
			\newline
			\textbf{Almacenamiento de palabra:} sw \$1,CONST(\$2) (almacena la palabra que se encuentra en el registro \$1  en la dirección \$2 + CONST (4 bytes))
			\newline
			\newline
			\textbf{Almacenamiento de media palabra:} sh \$1,CONST(\$2) (almacena la media palabra que se encuentra en el registro \$1  en la dirección \$2 + CONST (2 bytes))
			\newline
			\newline
			\textbf{Almacenamiento de byte:} sb \$1,CONST(\$2) (almacena el byte cargado en el registro \$1  en la dirección \$2 + CONST )
			\newline
			\newline
			\textbf{Carga del inmediato superior:} lui \$1,CONST  (carga un operando inmediato de 16 bits en los 16 bits del registro especificado.
			\newline
			\newline																						
			\textbf{Mover desde "high"(HI):} mfhi \$1 (mueve un valor de HI al registro)
			\newline
			\newline
			\textbf{Mover desde "low"(LO):} mflo \$1 (mueve un valor de LO al registro)
			\newline
			\newline
			\textbf{Mover :} move \$1, \$2 (mueve el contenido del registro \$2 al registro \$1)
			\newline
			\item\textbf{Lógicas}
			\newline
			\newline
			\textbf{And:} and \$1,\$2,\$3 (hace un And bit a bit entre los registros \$2 y \$3 almacendo el resultado en \$1)
			\newline
			\newline
			\textbf{And con inmediato:} andi \$1,\$2,CONST (hace un And bit a bit entre los registros \$2 y el valor binario de CONST almacendo el resultado en \$1)
			\newline
			\newline
			\textbf{Or:} or \$1,\$2,\$3 (hace un Or bit a bit entre los registros \$2 y \$3 almacendo el resultado en \$1)
			\newline
			\newline
			\textbf{Or con inmediato:} ori \$1,\$2,CONST (hace un Or bit a bit entre los registros \$2 y el valor binario de CONST almacendo el resultado en \$1)
			\newline
			\newline
			\textbf{Or exclusivo:} xor \$1,\$2,\$3 (hace un Xor bit a bit entre los registros \$2 y \$3 almacendo el resultado en \$1)
			\newline
			\newline
			\textbf{Nor:} nor \$1,\$2,\$3 (hace un Or bit a bit entre los registros \$2 y \$3 e invierte el resultado almacenándolo en \$1)
			\newline
			\newline
			\textbf{Inicializar si menor que:} slt \$1,\$2,\$3 (comprueba si el registro \$2 es menor a \$3, almacendo el resultado en \$1) 
			\newline
			\newline
			\textbf{Inicializar si menor que con inmediato:} slti \$1,\$2,CONST (comprueba si un registro es menor que una constante almacendo el resultado en \$1)

			\item\textbf{Desplazamiento de datos}
			\newline
			\newline
			\textbf{Desplazamiento lógico a la izquierda:} sll \$1,\$2,CONST (desplaza el registro \$2 CONST bits a la izquierda guardando el resultado en \$1)
			\newline
			\newline
			\textbf{Desplazamiento lógico a la derecha:} srl \$1,\$2,CONST (desplaza el registro \$2 CONST bits a la derecha, rellenado con ceros, guardando el resultado en \$1)
			\newline
			\newline
			\textbf{Desplazamiento aritmético a la derecha:} sra \$1,\$2,CONST (desplaza el registro \$2 CONST bits rellenando con el bit de signo correspondiente, guardando el resultado en \$1)
  			\newline
			\newline

			\item\textbf{Saltos condicionales}
			\newline
			\newline
			\textbf{Salto si igual:} beq \$1,\$2,CONST (salta a la instrucción situada en la dirección especificada si ambos registros son iguales)
			\newline
			\newline
			\textbf{Salto si no igual:} bne \$1,\$2,CONST (salta a la instrucción situada en la dirección especificada si ambos registros no son iguales)
			\newline
			\newline

			\item\textbf{Saltos incondicionales}
			\textbf{Salto:} j CONST (salta de forma incondicional a la instrucción almacenada en la dirección especificada)
			\newline
			\newline
			\textbf{Salto a registro:} jr \$1 (salta a la dirección almacenada en el registro especificado)
			\newline
			\newline
			\textbf{Salto y enlace:}	jal CONST (salta a la dirección almacenada en el registro especificado, guardando en \$31 la dirección de retorno, a la que se vuelve con jr \$31)
			\newline
			\newline
			\item\textbf{Punto flotante (coprocesador)}
			\newline
			\newline
 			\textbf{Carga: }l.s \$1, CONST (lee de la dirección CONST de memoria un real y lo almacena en \$1)
			\newline
			\newline
 			\textbf{Almacenamiento: }s.s \$1, CONST (escribe en la dirección CONST de memoria el real contenido en \$1)
			\newline
			\newline
 			\textbf{Suma: }	add.s \$1, \$2, \$3 (suma los registros \$2 y \$3 y guarda el resultado en \$1)
			\newline
			\newline
 			\textbf{Resta: }	sub.s \$1, \$2,\$3 (resta los registros \$2 y \$3 y guarda el resultado en \$1)
			\newline
			\newline
 			\textbf{Multiplicación: }	mul.s \$1, \$2, \$3 (multiplica los registros \$2 y \$3 y guarda el resultado en \$1)
			\newline
			\newline
 			\textbf{División: }	div.s \$1, \$2, \$3 (divide los registros \$2 y \$3 y guarda el resultado en \$1)
			\newline
			\newline
 			\textbf{Conversión entero a simple precisión:} cvt.s.w \$1,\$2 (convierte un número entero del registro \$2 a un número de preción simple y lo guarda en \$1)
			\newline
			\newline
			\textbf{Transferencia de Cpu al coprocesador de f.p.: } mtc1 \$1,\$2 (transfiere el registro \$2 de la CPU al registro \$1 del coprocesador de punto flotante)
			\newline
			\newline
			\end{itemize}
			
		\subsection{Directivas}
			Se explica brevemente el significado de las directivas utilizadas en ésta entrega.
			\begin{itemize}
			\item\textbf{.text dirección: }comienza la sección de texto de usuario en la dirección dada.
			\newline
			\item\textbf{.align N: }especifica un alineamiento para la siguiente directiva de datos. N especifica el alineamiento, y debe ser una potencia de 2.
			\newline
			\item\textbf{.globl Simb: }indica que el símbolo es exportado (lo inserta en la tabla de símbolos exportados).
			\newline
			\item\textbf{.extern Simb,t: }indica que el símbolo es importado y ocupa t octetos. Al tiempo, inserta lo inserta en la tabla de símbolos. Cada vez que un símbolo externo aparece en el programa se registra en la tabla de
símbolos importados.
			\newline
			\item\textbf{.ent etiqueta: }marca el comienzo de una subrutina.
			\newline
			\item\textbf{.end etiqueta: }marca el final de una subrutina.
			\newline
			\item\textbf{.set noreorder: }marca el inicio de una región del fichero fuente en la cual el ensamblador no reordena las instrucciones del programa.
			\newline
			\item\textbf{.set reorder: }marca el final de una región de no reordenación. A partir de ella, el ensamblador puede reordenar las instrucciones para mejorar la eficiencia del programa.
			\newline
			\item\textbf{.cpload registro: } toma un registro como argumento, el cual contiene la dirección de la función.
			\end{itemize}

		
			

	\section{Instrucciones para compilar}
			Para compilar el código se debe ejecutar el siguiente comando:
			\begin{verbatim}
					gcc -Wall -o tp1 tp1.c wc.S count.S
			 \end{verbatim}
                        Para facilitar la tarea se incluye un makefile en la versión digital de este trabajo práctico.
			\vspace{0.5cm}
					
	\section{Desarrollo}
		A partir de los conceptos teóricos desarrollados en la sección anterior (\ref{sec:InfoTeo}), se procedió a crear los módulos en \emph{mips32 assembly}. 
		
		\vspace{0.5cm}
		\subsection{Modo de Operación}
			
		
		
		\subsection{Ejemplos}
               
		     
	\section{Implementación}
	  \subsection{Código Fuente tp1.c}
\begin{scriptsize}
\begin{Verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int words;
int bytes;
int lines;

/*
int count(char c, int last_char)
{
	int ret = 0;
	switch (c)
	{
		case ' ':
		case '\t':	
			ret = 1;
			break;
		case '\n':		
			++lines;
			ret = 1;
			break;
		default:
			if (last_char)
				++words;
			break;
	}
	++bytes;
	return ret;
}

void wc(int fd)
{
	char c;
	int last_char;
	last_char = 1;
	while (read(fd, &c, 1) > 0) {
		last_char = count(c, last_char);
	}
}
*/
int count(char, int);
void wc(int fd);

void print_help(){
	fprintf(stdout, 
	"Usage:\n"
	"tp1 -h\n"
	"tp1 -V\n"
	"tp1 [options] [file...]\n"
	"Options:\n"
	"-v, --version Print version and quit.\n"
	"-h, --help Print this information and quit.\n"
	"-w, --words Print the number of words.\n"
	"-l, --lines Print the number of lines.\n"
	"-c, --bytes Print the number of bytes.\n");
}

void print_version(){
	fprintf(stdout, "Version 1.0\n");
}

void print(int options, char* filename) {
	char separador = ' ';

	if (filename == 0) {
		separador = '\t';
		if (options != 1 || options != 2 || options != 4)
			printf("%c", separador);
	}

	switch (options) {
		case 0:
		case 7:
			printf("%d%c%d%c%d", lines, separador, words, separador, bytes);
			break;
		case 1:
			printf("%d", words);
			break;
		case 2:
			printf("%d", lines);
			break;
		case 3:
			printf("%d%c%d", lines, separador, words);
			break;
		case 4:
			printf("%d", bytes);
			break;
		case 5:
			printf("%d%c%d", words, separador, bytes);
			break;
		case 6:
			printf("%d%c%d", lines, separador, bytes);
			break;
		default:
			break;
	}

	if (filename != 0)
		printf(" %s\n", filename);
	else
		printf("\n");		
}

void print_total(int options, int lines, int words, int bytes) {
	printf("\t%d\t%d\t%d\ttotal", lines, words, bytes);
}

void reset() {
	lines = 0;
	bytes = 0;
	words = 0;
}

int main(int argc, char** argv) {
	int total_lines = 0;
	int total_bytes = 0;
	int total_words = 0;
	extern int optind, opterr, optopt;
	/* Una cadena que lista las opciones cortas válidas */
	const char* const opcionesCortas = "wlcvh";
	int options = 0;
	int i, fd, c;
	/* Una estructura de varios arrays describiendo las opciones largas */
	const struct option opcionesLargas[] = {
	  { "help",	  no_argument, NULL,'h'},
	  { "version", no_argument, NULL,'v'},
	  { "words",no_argument, NULL,'w'},
	  { "lines",no_argument, NULL,'l'},
	  { "bytes",no_argument, NULL,'c'},
	  { NULL,     no_argument, NULL, 0 }
	};

	opterr = 0;

	while ((c = getopt_long(argc, argv, opcionesCortas, opcionesLargas, NULL)) != -1)
	 switch (c)
	   {
	   case 'w':
	     options += 1;
	     break;
	   case 'l':
	     options += 2;
	     break;
	   case 'c':
	     options += 4;
	     break;
	   case 'h':
	     print_help();
	     exit(EXIT_SUCCESS);
	   case 'v':
	     print_version();
	     exit(EXIT_SUCCESS);
	   case '?':
	     fprintf (stderr, "Unknown option character\n");
	     print_help();
	     exit(EXIT_FAILURE);
	   default:
	     abort ();
	   }
	
	if(optind == -1 || optind == argc)
    	{
		reset();
        	wc(STDIN_FILENO);
		print(options, STDIN_FILENO);
    	}
    	else
    	{
        	for(i=optind; i<argc; ++i)
        	{			
			reset();
            		fd = open(argv[i], O_RDONLY);
    			if( fd == -1)
        			fprintf(stderr, "%s: No such file or directory\n", argv[i]);
			else {
	    			wc(fd);
				print(options, argv[i]);
    				close(fd);
				total_lines += lines;
				total_bytes += bytes;
				total_words += words;
			}		
			
        	}
		if (argc - optind > 1) {
			lines = total_lines;
			words = total_words;
			bytes = total_bytes;
			print(options, "total");
		}
    	}
	return 0;
}

\end{Verbatim}
\end{scriptsize}
	\subsection{Código Fuente wc.S}
\begin{scriptsize}
\begin{Verbatim}
# wc.S
#
# - Argumentos:
#	* fd: int
#
# - Stack Frame:
#	* Los 24 superiores se usan para el SRA.	
#	* Los 16 inferiores son espacio reservado para 	
#	  el ABA.

#define 	SSIZE		40
#define		O_FD		36
#define		O_LAST_CHAR	32
#define		O_C			28
#define		O_RA		24
#define		O_FP		20
#define		O_GP		16
#define		O_ARG0		(SSIZE)

#include <mips/regdef.h>
#include <sys/syscall.h>

#void wc(int fd)
#{
#	char c;
#	int last_char = 1;
#	while (read(fd, &c, 1) > 0) {
#		last_char = count(c, last_char);
#	}
#}

.text
.align 2
.globl 	wc
.ent 	wc

wc:
		.frame $fp, SSIZE, ra
		.set noreorder
		.cpload t9
		.set reorder

		subu	sp, sp, SSIZE			#creo el stack
		sw	$fp, O_FP(sp)
		.cprestore O_GP
		sw	ra, O_RA(sp)		
		sw	zero, O_C(sp)
	
		move 	$fp, sp
		sw 	a0, O_ARG0($fp)
		sw	a0, O_FD($fp)
		li	t0, 1
		sw	t0, O_LAST_CHAR($fp)
loop:		li	v0, SYS_read
		lw	a0, O_FD($fp)
		la	a1, O_C($fp)
		li	a2, 1
		syscall
		beqz	v0, unwind
		move	a0, zero
		lb	a0, O_C($fp)
		lw	a1, O_LAST_CHAR($fp)
		la	t9, count
		jal	ra, t9
		sw	v0, O_LAST_CHAR($fp)
		b	loop

unwind:		move 	sp, $fp				#destruyo el stack
		lw	gp, O_GP($fp)
		lw 	ra, O_RA($fp)
		lw	$fp, O_FP($fp)
		addiu 	sp, sp, SSIZE
		jr 	ra	

.end 	wc
\end{Verbatim}
\end{scriptsize}

\subsection{Código count.S}


\begin{scriptsize}
\begin{Verbatim}
# count.S
#
# - Argumentos:
#	* fd: int
#
# - Stack Frame:
#	* Tamaño: 8 bytes (por ser leaf, guardo gp y fp)

#define 	SSIZE		8
#define		O_FP		4
#define		O_GP		0
#define		O_ARG0		(SSIZE)
#define		O_ARG1		SSIZE + 4

#define	ASCII_SPACE	32
#define	ASCII_HTAB	9
#define	ASCII_NEWLINE	10
#define ASCII_CRETURN	13
#define ASCII_VTAB	11
#define ASCII_FFEED	12

#include <mips/regdef.h>
#include <sys/syscall.h>

#int count(char c, int last_char)
#{
#	int ret = 1;
#	switch (c)
#	{
#		case ' ':
#		case '\t':
#		case '\r':
#		case '\f':
#		case '\v'
#			break;
#		case '\n':		
#			++lines;
#			break;
#		default:
##			if (last_char)
#				++words;
#			ret = 0;
#			break;
#	}
#	++bytes;
#	return ret;
#}

.text
.align 2
.globl 	count
.ent 	count

count:			
	.frame $fp, SSIZE, ra
	.set noreorder
	.cpload t9
	.set reorder


			subu	sp, sp, SSIZE			#creo el stack
			sw	$fp, O_FP(sp)
			.cprestore O_GP		
			
			move 	$fp, sp
			sb 	a0, O_ARG0($fp)
			sw	a1, O_ARG1($fp)
		
			move	t0, zero
			lb	t0, O_ARG0($fp)
			
			li	v0, 1
			beq	t0, ASCII_SPACE, fin			
			beq	t0, ASCII_HTAB, fin
			beq	t0, ASCII_CRETURN, fin
			beq	t0, ASCII_FFEED, fin
			beq	t0, ASCII_VTAB, fin
			bne	t0, ASCII_NEWLINE, default
			lw	t1, lines
			addiu	t1, t1, 1
			sw	t1, lines
			b	fin
default:		li	v0, 0
			beqz	a1, fin
			lw	t1, words
			addiu	t1, t1, 1
			sw	t1, words
			
fin:			lw	t1, bytes
			addiu	t1, t1, 1
			sw	t1, bytes
		
			move 	sp, $fp					#destruyo el stack
			lw	gp, O_GP($fp)
			lw	$fp, O_FP($fp)
			addiu 	sp, sp, SSIZE
			jr 	ra
.end 	count


	
\end{Verbatim}
\end{scriptsize}



\section{Pruebas}
Los archivos utilizados para esta sección se encuentran en la versión digital del presente trabajo en la carpeta tests.\\
\subsection{Corridas de Prueba}
\subsubsection{Ayuda}
\begin{verbatim}
 # ./tp1 -h
Usage:
tp1 -h
tp1 -V
tp1 [options] [file...]
Options:
-v, --version Print version and quit.
-h, --help Print this information and quit.
-w, --words Print the number of words.
-l, --lines Print the number of lines.
-c, --bytes Print the number of bytes.
\end{verbatim}

\subsubsection{Versión}
\begin{verbatim}
 # ./tp1 -v
Version 1.0
\end{verbatim}

\subsubsection{Archivo Vacío}
\begin{verbatim}
# ./tp1 vacio.txt
0 0 0 vacio.txt
# wc vacio.txt
       0       0       0 vacio.txt
\end{verbatim}

\subsubsection{Entrada estandar}
\begin{verbatim}
# echo Hola como te va | ./tp1
        1       4       16
# echo Hola como te va | wc   
       1       4      16

# echo "Don't Panic" | ./tp1
        1       2       12
# echo "Don't Panic" | wc
       1       2      12
\end{verbatim}


\subsubsection{Archivos binarios}
\begin{verbatim}
# ./tp1 random64.txt
1 4 64 random64.txt
# wc random64.txt
       1       4      64 random64.txt
\end{verbatim}

\begin{verbatim}
# ./tp1 random1024.txt
5 19 1024 random1024.txt
# wc random1024.txt
       5      19    1024 random1024.txt
\end{verbatim}

\begin{verbatim}
# ./tp1 random2048.txt
5 40 2048 random2048.txt
# wc random2048.txt
       5      40    2048 random2048.txt

\end{verbatim}
\subsubsection{Varios Archivos}
\begin{verbatim}
# ./tp1 vacio.txt random64.txt random1024.txt random2048.txt
0 0 0 vacio.txt
1 4 64 random64.txt
5 19 1024 random1024.txt
5 40 2048 random2048.txt
11 63 3136 total

# wc vacio.txt random64.txt random1024.txt random2048.txt
       0       0       0 vacio.txt
       1       4      64 random64.txt
       5      19    1024 random1024.txt
       5      40    2048 random2048.txt
      11      63    3136 total
\end{verbatim}

\subsubsection{Opciones}
\begin{verbatim}
# ./tp1 -w -l random64.txt
1 4 random64.txt
# wc -w -l random64.txt
       1       4 random64.txt
\end{verbatim}

\begin{verbatim}
# ./tp1 -c random64.txt random1024.txt
64 random64.txt
1024 random1024.txt
1088 total
# wc -c random64.txt random1024.txt
      64 random64.txt
    1024 random1024.txt
    1088 total

\end{verbatim}

\section{Diagramas}
En los siguientes diagramas se muestran los stack de las funciones \emph{wc} y \emph{count}

\subsection{Stack de wc}
Tamaño: 40 bytes (24 bytes SRA + 16 bytes ABA).\\
\begin{tabular}{|c|c|c|}

		\hline
		36 & O\_FD & SRA\\
		\hline
		32 & O\_LAST\_CHAR & SRA\\
		\hline
		28 & O\_C & SRA\\
		\hline
		24 & O\_RA & SRA\\	
		\hline
		20 & O\_FP & SRA\\	
		\hline
		16 & O\_GP & SRA\\	
		\hline
		12 & a3 & ABA\\	
		\hline
		8 & a2 & ABA\\	
		\hline
		4 & a1 & ABA\\	
		\hline
		0 & a0 & ABA\\	
		\hline
	\end{tabular}

\subsection{Stack de count}
Tamaño: 8 bytes (SRA).\\
\begin{tabular}{|c|c|c|}

		\hline
		4 & O\_FP & SRA\\	
		\hline
		0 & O\_GP & SRA\\	
		\hline
	\end{tabular}

\section{Conclusiones}

Con el desarrollo de este Trabajo Práctico hemos podido simular el comportamiento del compilador a la hora de generar el código fuente en lenguaje ensamblador (.S). Tal conclusión se ha alcanzado a partir de verificar los resultados obtenidos habiendo realizado todos los procedimientos en un solo lenguaje (C) y observando que los mismos coinciden. 
\newline
A su vez hemos podido interiorizarnos en el concepto de ABI, aplicando dicha interface a la presente entrega. Para ello, hemos investigado el conjunto de instrucciones que nos provee MIPS y las hemos aplicado, respetando las Function Calling Conventions[2]. Además hemos ahondando en el tema de las directivas del \emph{assembly} para entender mejor su funcionamiento.


Para finalizar, hemos concluido que existen ventajas y desventajas a la hora de programar en assembly respecto de un lenguaje de alto nivel.

La primer ventaja a destacar es la velocidad del programa. Muchas veces el código generado por un compilador es menos eficiente que el equivalente que un programador escribiría. La razón es que el compilador no posee la inteligencia de un ser humano y podría desperdiciar tiempo realizando procesos que no son necesarios. Este aspecto no es absoluto dado que tambíen depende de la habilidad del programador. Además, frente al problema resuelto en este trabajo no se percibe esta diferencia.

Otro aspecto a destacar es el tama\~no del código generado. Por la misma razón que se menciono anteriormente, un compilador genera más código de maquina que el necesario y el tama\~no del programa ejecutable crece.

Por otro lado, al ser un lenguaje más primitivo, se tienen ciertas desventajas respecto a los lenguajes de alto nivel. 

Una de ellas es el tiempo de programación, dado que se requieren más instrucciones para realizar el mismo proceso en comparación con un lenguaje de alto nivel. 

Muchas veces el código assembly es menos entendible. En nuestro caso, el codigo C desarrollado es mucho más comprensible que el assembly equivalente.

Otra desventaja que hemos experemintado es que los código fuente son mucho más grandes, razón por la cual aumenta el tiempo de desarrollo. En nuestro caso particular esta desventaja se ha hecho visible al exponer los códigos en C correspondientes a los módulos desarrollados en assembly. 

Por último, la falta de portabilidad es otra desventaja, dado que existe un lenguaje ensamblador para cada máquina. En cambio, programando en un lenguaje de alto nivel esta desventaja es mucho menos notoria ya que al recompilar el código (realizado para una máquina) adecuadamente la mayoría del mismo  será reutilizable en otra.


Finalmente podemos agregar que, dado que la programación en lenguaje ensamblador depende de la arquitectura del computador sobre el cual se trabaja, es importante para entender el funcionamiento interno de la máquina comprendiendo cómo es su estructura básica.


\begin{thebibliography}{99}

\bibitem{MIP96} MIPS RISC Processor Supplement, ``SYSTEM V APPLICATION BINARY INTERFACE Intel,'' 1996

\bibitem{MIP} ``MIPS ABI: Function Calling Convention,'' Organización de computadoras - 66.20

\bibitem{WIK} http://es.wikipedia.org/wiki/MIPS\_\%28procesador\%29

\end{thebibliography}


\end{document}
